﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using CharacterTrailLibrary.CustomModels;
using CharacterTrailLibrary.Interface;
using CharacterTrailLibrary.Persist;
using CharacterTrailLibrary.Persist.BLL.Model;
using CharacterTrailLibrary.Persist.DAL.Dao;
using CharacterTrailLibrary.Security;
using Telegnosis.Framework.Constants;
using Telegnosis.Framework.DataAccess.DB;

namespace CharacterTrailLibrary.Impl
{
    public class BomImpl : IBom
    {
        public void SaveBom(Persist.BLL.Model.TBomMainModel bomMainModel, Persist.BLL.Model.TBomEntryModel bomEntryModel)
        {
            //检查产品和物料
            if(bomMainModel.ProductItemId !=bomEntryModel.ProductItemId 
                || bomMainModel.ProductVersion !=bomEntryModel.ProductVersion )
            {
                throw new Exception("产品的编码和版本必须和物料的一致！");
            }

            if(bomMainModel.CheckStatus == 1)
            {
                throw new Exception("该产品已经审核，不能修改物料，请先反审核！");
            }

            ITrans trans = DAHelper.GetSqlTrans();
            var bomMainDao = new TBomMainDao { Trans = trans };
            var bomEntryDao = new TBomEntryDao { Trans = trans };
            try
            {
                trans.Begin();
                var bomMain = this.GetBomMainModel(bomMainModel.ProductItemId, bomMainModel.ProductVersion);
                if (bomMain == null)
                {
                    //执行新增
                    bomMainModel.ProductItemName = String.Empty;
                    bomMainModel.ProductItemNumber = String.Empty;
                    bomMainDao.InsertItem(bomMainModel.CreateOrm());
                }
                var bomEntry = this.GetBomEntryModel(bomEntryModel.ProductItemId, bomEntryModel.ProductVersion,
                                                     bomEntryModel.MaterialItemId);
                if (bomEntry == null)
                {
                    int idx = GetMaxBomEntryIdx(bomEntryModel.ProductItemId, bomEntryModel.ProductVersion);
                    bomEntryModel.Idx = idx;
                    //执行新增
                    bomEntryModel.ProductItemName = String.Empty;
                    bomEntryModel.ProductItemNumber = String.Empty;
                    bomEntryModel.MaterialItemName = String.Empty;
                    bomEntryModel.MaterialItemNumber = String.Empty;
                    bomEntryDao.InsertItem(bomEntryModel.CreateOrm());
                }
                else
                {
                    throw new Exception(String.Format("产品{0}版本{1}已经包括了物料{2}！",
                        bomEntryModel.ProductItemNumber, bomEntryModel.ProductVersion,
                                                     bomEntryModel.MaterialItemNumber));
                }
                trans.Commit();
            }
            catch (Exception exception)
            {
                trans.RollBack();
                throw ;
            }
        }

        public void DeleteBomEntry(Persist.BLL.Model.TBomEntryModel bomEntryModel)
        {
            var bomMainModel = GetBomMainModel(bomEntryModel.ProductItemId,
                                                             bomEntryModel.ProductVersion);
            if (bomMainModel.CheckStatus == 1)
            {
                throw new Exception("该产品已经审核，不能删除物料！");
            }

            var bomEntryDao = new TBomEntryDao();
            bomEntryDao.DeleteItem(bomEntryModel.CreateOrm());
        }

        public List<TBomMainModel> GetBomMainModels()
        {
            var sqlWhere = new SqlItem();
            sqlWhere.Text = " 15=15 order by ProductItemNumber";
            var dao = new TBomMainDao();
            return dao.GetList(sqlWhere);
        }


        public TBomMainModel GetBomMainModel(int productItemId, string productVersion)
        {
            string condition = " ProductItemId = {0} and ProductVersion = '{1}'";
            condition = string.Format(condition, productItemId, productVersion);
            var sqlWhere = new SqlItem();
            sqlWhere.Text = condition;
            var dao = new TBomMainDao();
            var list =  dao.GetList(sqlWhere);
            if (list.Count > 0)
                return list[0];
            return null;
        }

        public TBomEntryModel GetBomEntryModel(int productItemId, string productVersion, int materialItemId)
        {
            string condition = " ProductItemId = {0} and ProductVersion = '{1}' and MaterialItemId = {2}";
            condition = string.Format(condition, productItemId, productVersion, materialItemId);
            var sqlWhere = new SqlItem();
            sqlWhere.Text = condition;
            var dao = new TBomEntryDao();
            var list = dao.GetList(sqlWhere);
            if (list.Count > 0)
                return list[0];
            return null;
        }


        public List<TBomEntryModel> GetBomEntryModelsByProduct(int productItemId, string productVersion)
        {
            string condition = " ProductItemId = {0} and ProductVersion = '{1}' ";
            condition = string.Format(condition, productItemId, productVersion);
            var sqlWhere = new SqlItem();
            sqlWhere.Text = condition;
            var dao = new TBomEntryDao();
            return  dao.GetList(sqlWhere);
        }


        public List<string> GetDistinctProductVersion(int productItemId)
        {
            String querySql =  "select distinct ProductVersion from dbo.tbommain where ProductItemId={0} ";
            querySql = string.Format(querySql, productItemId);
            var  sqlAccess = DAHelper.GetSqlAccess();
            var dataSet = sqlAccess.GetDataset( new SqlItem(querySql)) ;
            var list = new List<string>();
            foreach (DataRow dataRow in dataSet.Tables[0].Rows)
            {
                list.Add(dataRow["ProductVersion"].ToString().Trim());
            }
            return list;
        }


        public int GetMaxBomEntryIdx(int productItemId, string productVersion)
        {
            string querySql = "select isnull( max(Idx),0) +1 from dbo.TBomEntry where ProductItemId = {0} and ProductVersion = '{1}' ";
            querySql = string.Format(querySql, productItemId, productVersion);
            var sqlAccess = DAHelper.GetSqlAccess();
            var dataSet = sqlAccess.GetDataset(new SqlItem(querySql));
            return int.Parse(dataSet.Tables[0].Rows[0][0].ToString());
        }


        public List<TBomEntryModel> GetBomEntryModelsByCondition(string condition)
        {
            var sqlWhere = new SqlItem();
            sqlWhere.Text = condition + " order by ProductItemNumber,ProductVersion,Idx";
            var dao = new TBomEntryDao();
            return dao.GetList(sqlWhere);
        }


        public void UpdateBomEntryModel(int productItemId, string productVersion, 
            int materialItemId, TBomEntryModel bomEntryModel)
        {

            var bomMainModel = GetBomMainModel(bomEntryModel.ProductItemId,
                                                             bomEntryModel.ProductVersion);
            if (bomMainModel.CheckStatus == 1)
            {
                throw new Exception("该产品已经审核，不能修改！");
            }

            //if (String.IsNullOrEmpty(productItemId)) throw new Exception("产品编码为空！");
            if (String.IsNullOrEmpty(productVersion)) throw new Exception("产品名称为空！");
            //if (String.IsNullOrEmpty(materialItemId)) throw new Exception("物料编码为空！");

            ISqlAccess sqlAccess = DAHelper.GetSqlAccess();
            string sqlUpdate1 = "update TBomEntry set MaterialItemId = {0}," +
                "Qty={1},ProcedureNo='{2}',ProcedureName = '{3}' where productItemId={4} and productVersion='{5}' and MaterialItemId= {6} ";
            //Qty  decimal(28, 4) default 0,--数量
            //ProcedureNo  varchar(255)   not null ,--工序号
            //ProcedureName  varchar(255) ,--工序名称
            sqlUpdate1 = String.Format(sqlUpdate1, bomEntryModel.MaterialItemId,bomEntryModel.Qty,
               bomEntryModel.ProcedureNo,bomEntryModel.ProcedureName,
               productItemId,  productVersion, materialItemId);

            try
            {
                sqlAccess.ExecuteTransaction(new SqlItem[] { new SqlItem(sqlUpdate1) });
            }
            catch (Exception exception)
            {
                throw new Exception("记录修改错误：" + exception.Message);
            }
        }


        public void CheckBomMain(TBomMainModel bomMainModel)
        {
            var model = this.GetBomMainModel(bomMainModel.ProductItemId, bomMainModel.ProductVersion);
            if(model == null)
            {
                throw new Exception("数据库中找不到改产品！");
            }
            if(model.CheckStatus != 0)
            {
                throw new Exception("改产品已经审核！");
            }

            var list = this.GetBomMainModelsByCondition(string.Format(" ProductItemId = {0} and CheckStatus = 1", bomMainModel.ProductItemId));
            if(list.Count >0)
            {
                throw new Exception("已经存在版本号为{0}的改产品已经审核，同一种产品只能有一个版本处于审核状态！");
            }

            model.CheckStatus = 1;
            model.CheckId = UserSession.CurrentUser.UserId;
            //用户名
            model.ExtChar1 = UserSession.CurrentUser.UserName;
            model.CheckDate = DateTime.Now;
            var dao = new TBomMainDao();
            dao.UpdateItem(model.CreateOrm());
        }

        public void UnCheckBomMain(TBomMainModel bomMainModel)
        {
            var model = this.GetBomMainModel(bomMainModel.ProductItemId, bomMainModel.ProductVersion);
            if (model == null)
            {
                throw new Exception("数据库中找不到改产品！");
            }
            if (model.CheckStatus != 1)
            {
                throw new Exception("改产品并未审核！");
            }

            if (model.CheckId != UserSession.CurrentUser.UserId)
            {
                throw new Exception("只有审核操作人员才能反审核改产品！");
            }

            model.CheckStatus = 0;
            model.UnCheckDate = DateTime.Now;
            model.UnCheckId = UserSession.CurrentUser.UserId;
            //用户名
            model.ExtChar1 = string.Empty;
            //反审核用户名
            model.ExtChar2 = UserSession.CurrentUser.UserName;
            var dao = new TBomMainDao();
            dao.UpdateItem(model.CreateOrm());
        }


        public List<TBomMainModel> GetBomMainModelsByCondition(string condition)
        {
            var sqlWhere = new SqlItem();
            sqlWhere.Text = condition;
            var dao = new TBomMainDao();
            return dao.GetList(sqlWhere);
        }


        public List<VBomEntryAndMainModel> GetVBomEntryAndMainModelByCondition(string condition)
        {
            var sqlWhere = new SqlItem();
            sqlWhere.Text = condition + " order by ProductItemId,ProductVersion,Idx";
            var dao = new VBomEntryAndMainDao();
            return dao.GetList(sqlWhere);
        }


        public List<CustomModels.ProductItemModel> BuildProductTree(int productItemId, string productVersion)
        {
            var list = new List<ProductItemModel>();
            var productModel = this.GetBomMainModel(productItemId, productVersion);
            if(productModel == null)
            {
                throw new Exception("产品Bom表头不存在！");
            }

            var model = BomMainToProductItemModel(productModel);
            list.Add(model);
            RecursiveBuild(list, model);
            return list;
        }

        private void RecursiveBuild(List<ProductItemModel> list ,ProductItemModel productItemModel)
        {
            var listTmp = GetBomEntryModelsByProduct(productItemModel.ProductItemId, productItemModel.ProductVersion);
            foreach (var bomEntryModel in listTmp)
            {
                var model = BomEntryToProductItemModel(bomEntryModel);
                model.ParentProductId = productItemModel.ProductItemNumberAndVersion;
                list.Add(model);

                var listTmp2 = this.GetBomMainModelsByCondition(string.Format(" ProductItemId = {0} and CheckStatus = 1",model.ProductItemId));
                
                if (listTmp2.Count > 0)
                {
                     var m = BomMainToProductItemModel(listTmp2[0]);
                    RecursiveBuild(list, m);
                }
            }
        }

// ReSharper disable MemberCanBeMadeStatic.Local
        private ProductItemModel BomMainToProductItemModel(TBomMainModel bomMainModel)
// ReSharper restore MemberCanBeMadeStatic.Local
        {
            var model = new ProductItemModel
                            {
                                Idx = 1,
                                ParentProductId = string.Empty,
                                ProcedureName = string.Empty,
                                ProcedureNo = string.Empty,
                                ProductItemId = bomMainModel.ProductItemId,
                                ProductItemName = bomMainModel.ProductItemName,
                                ProductItemNumber = bomMainModel.ProductItemNumber,
                                ProductVersion = bomMainModel.ProductVersion,
                                Qty = 0,
                                CheckStateDesc = (bomMainModel.CheckStatus == 1 ? ProductItemModel.CheckStateYes : ProductItemModel.CheckStateNo)
                            };
            return model;
        }


// ReSharper disable MemberCanBeMadeStatic.Local
        private ProductItemModel BomEntryToProductItemModel(TBomEntryModel bomEntryModel)
// ReSharper restore MemberCanBeMadeStatic.Local
        {
            var model = new ProductItemModel
                            {
                                Idx = bomEntryModel.Idx,
                                ParentProductId = string.Empty,
                                ProcedureName = bomEntryModel.ProcedureNo,
                                ProcedureNo = bomEntryModel.ProcedureName,
                                ProductItemId = bomEntryModel.MaterialItemId,
                                ProductItemName = bomEntryModel.MaterialItemName,
                                ProductItemNumber = bomEntryModel.MaterialItemNumber,
                                ProductVersion = bomEntryModel.ProductVersion,
                                Qty = bomEntryModel.Qty
                            };
            return model;
        }


        public List<TBomEntryModel> GetBomEntryModelsByProduct(int productItemId, string productVersion, string procedureNo)
        {
            string condition = " ProductItemId = {0} and ProductVersion = '{1}' and ProcedureNo = '{2}'";
            condition = string.Format(condition, productItemId, productVersion, procedureNo);
            var sqlWhere = new SqlItem();
            sqlWhere.Text = condition;
            var dao = new TBomEntryDao();
            return dao.GetList(sqlWhere);
        }

        public List<ProductItemModel> BuildProductTree2(int productItemId, string productVersion)
        {
            var list = new List<ProductItemModel>();
            var productModel = this.GetBomMainModel(productItemId, productVersion);
            if (productModel == null)
            {
                throw new Exception("产品Bom表头不存在！");
            }

            var model = BomMainToProductItemModel(productModel);

            RecursiveBuild2(list, model);

            return list;
        }

        private void RecursiveBuild2(List<ProductItemModel> list, ProductItemModel parentProductItemModel)
        {
            //the first node add to the list 
            list.Add(parentProductItemModel);

            var listTmp = GetBomEntryModelsByProduct(parentProductItemModel.ProductItemId, parentProductItemModel.ProductVersion);

            foreach (var bomEntryModel in listTmp)
            {
                var listTmp2 = this.GetBomMainModelsByCondition(string.Format(" ProductItemId = {0}  ",
                                                                              bomEntryModel.MaterialItemId));
                if (listTmp2.Count > 0)
                {
                    foreach (var bomMainModel in listTmp2)
                    {
                        var m = BomMainToProductItemModel(bomMainModel);
                        m.ParentProductVersion = parentProductItemModel.ProductVersion;
                        m.ParentProductItemNumber = parentProductItemModel.ProductItemNumber;

                        //m.ParentProductId = m.ParentProductItemNumber + "+" + m.ParentProductVersion;

                        m.ParentProductId = parentProductItemModel.ModelKey;

                        m.Qty = bomEntryModel.Qty;
                        RecursiveBuild2(list, m);
                    }
                }
                else
                {
                    var model = BomEntryToProductItemModel(bomEntryModel);
                    model.ParentProductVersion = parentProductItemModel.ProductVersion;
                    model.ParentProductItemNumber = parentProductItemModel.ProductItemNumber;

                    //model.ParentProductId = model.ParentProductItemNumber + "+" + model.ParentProductVersion;

                    model.ParentProductId = parentProductItemModel.ModelKey;

                    model.ImageIndex = 1;
                    model.IsLeafNode = true;
                    list.Add(model);
                }
            }
        }

        public void DeleteBomMainAndEntry(TBomMainModel bomMainModel)
        {
            var main = GetBomMainModel(bomMainModel.ProductItemId, bomMainModel.ProductVersion);
            if(main == null)
            {
                throw new Exception("没有相关的Bom产品！");
            }
            if(main.CheckStatus == 1)
            {
                throw new Exception("Bom产品已经审核，不能删除！");
            }
            var list = GetBomEntryModelsByProduct(main.ProductItemId, main.ProductVersion);

            ITrans trans = DAHelper.GetSqlTrans();
            var bomMainDao = new TBomMainDao { Trans = trans };
            var bomEntryDao = new TBomEntryDao { Trans = trans };
            try
            {
                trans.Begin();
                //删除主表
                bomMainDao.DeleteItem(main.CreateOrm());

                //删除从表
                foreach (var bomEntryModel in list)
                {
                    bomEntryDao.DeleteItem(bomEntryModel.CreateOrm());
                }
                trans.Commit();
            }
            catch (Exception exception)
            {
                trans.RollBack();
                throw;
            }
        }
    }
}
